export default {
  id: 'tags-check',
  description: '检测XML的标签',
  init(parser, reporter, options, tags) {
    let stack = []

    parser.addListener('tagstart', (event) => {
      const attrs = event.attrs
      const col = event.col + event.tagName.length + 1
      const tagName = event.tagName
      // tags为空不进行校验
      if (!tags || tags.length === 0) {
        return
      }
      // 重新统计栈
      if (event.lastEvent.type === 'start') {
        stack = []
      }
      stack.push(tagName)
      if (tags[tagName]) {
        // 当前是顶级标签
        if (stack.length === 1) {

          // 判断是否为顶级标签
          if (tags['!top'].indexOf(tagName) === -1) {
            reporter.error(
              `标签 <${tagName}> 不是顶级标签`,
              event.line,
              col,
              this,
              event.raw
            )
          }
        } else {
          // 父级标签
          const parentTagName = stack[stack.length - 2]
          // 判断当前标签是否是父级标签的子级
          if (tags[parentTagName] && Array.isArray(tags[parentTagName].children) && tags[parentTagName].children.indexOf(tagName) === -1) {
            reporter.error(
              `标签 <${tagName}> 不是标签 <${parentTagName}> 的子级`,
              event.line,
              col,
              this,
              event.raw
            )
          }
        }

        const currentTagType = tags[tagName]

        if (currentTagType.attrs) {
          const tagsAttrs = currentTagType.attrs
          const tagsAttrsKeys = Object.keys(tagsAttrs)

          attrs.forEach((attr) => {
            if (tagsAttrsKeys.indexOf(attr.name) === -1) {
              reporter.error(
                `标签 <${tagName}> 没有属性 ['${attr.name}']`,
                event.line,
                col + attr.index,
                this,
                event.raw
              )
            } else {
              if (tagsAttrs[attr.name] && tagsAttrs[attr.name].length > 0 && tagsAttrs[attr.name].indexOf(attr.value) === -1) {
                // 如果提示选项中有非数字选项，那么认为这个值为固定的几个值，需要提示
                if (tagsAttrs[attr.name].some((value) => { return isNaN(Number(value)) })) {
                  reporter.error(
                    `属性 [${attr.name}] 从来没用过这个值：'${attr.value}'`,
                    event.line,
                    col + attr.index,
                    this,
                    event.raw
                  )
                }
              }
            }
          })
        }
      } else {
        reporter.error(
          `标签 <${tagName}> 不存在`,
          event.line,
          col,
          this,
          event.raw
        )
      }

      // 自闭合节点进行匹配出栈操作
      if (event.close) {
        if (stack[stack.length - 1] === tagName) {
          stack.length = stack.length - 1
        }
      }
    })

    parser.addListener('tagend', (event) => {
      // tags为空不进行校验
      if (!tags || tags.length === 0) {
        return
      }
      const tagName = event.tagName
      // 结束节点进行匹配出栈操作
      if (stack[stack.length - 1] === tagName) {
        stack.length = stack.length - 1
      }
    })
  }
}
